package com.shenghua.controller;

import com.alibaba.fastjson.JSON;
import com.shenghua.dao.mapper.AppFileMapper;
import com.shenghua.dao.model.AppFile;
import com.shenghua.dao.model.User;
import com.shenghua.service.AppFileService;
import com.shenghua.service.BeanFactoryService;
import com.shenghua.utils.PicUtil;
import com.shenghua.utils.StringUtils;
import com.shenghua.utils.beans.Constants;
import com.shenghua.utils.beans.Dto;
import com.shenghua.utils.beans.ErrorCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2019/8/31.
 */
@Controller
@RequestMapping("/file")
public class FileController extends BaseController {

    private Logger logger = LoggerFactory.getLogger(FileController.class);

    @Value("${app-path}")
    private  String appPath;

    @Autowired
    private AppFileMapper appFileMapper;

    @Autowired
    private AppFileService appFileService;

    @Autowired
    private BeanFactoryService beanFactoryService;

    // 上传临时图片
    @RequestMapping(value = "/upload")
    @ResponseBody
    public String upload(HttpServletRequest request) {
        Dto<String> dto = new Dto<>();
        User user = (User)request.getSession().getAttribute("userSession");
        if(null == user){
            logger.debug("[FileController] upload 用户未登录");
            dto.ReturnFail(null, ErrorCode.USER_NOT_LOGIN);
            return JSON.toJSONString(dto);
        }
        MultipartFile file = null;
        List<Map<String, String>> filePath = new ArrayList<>();
        if (request instanceof MultipartHttpServletRequest) {
            try {
                // 转换多媒体请求对象
                MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
                // 获取上传的文件列表
                Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
                for (Map.Entry<String, MultipartFile> entity : fileMap.entrySet()) {
                    file = entity.getValue();
                    logger.info("[FileController] upload 上传文件："+JSON.toJSONString(file.getOriginalFilename()));
                    logger.info("[FileController] upload 图片是否为空："+(file==null));
                    if(null == file) {
                        dto.ReturnFail(null, ErrorCode.FAILURE);
                        return JSON.toJSONString(dto);
                    }

                    String uploadUrl = PicUtil.generateImageFileName1(file);// 文件名

                    String basePath = retUploadPath();// 保存路径

                    logger.info("[FileController] upload 开始上传文件");
                    Dto<String> ret = PicUtil.uploadImage(file, uploadUrl, basePath);

                    if(!ret.isSuccess()) {
                        logger.info("[FileController] upload 文件上传失败");
                        dto.ReturnFail(null, ErrorCode.FAILURE);
                        return JSON.toJSONString(dto);
                    }
                    //保存文件
                    AppFile appFile = beanFactoryService.createAppFile(user, file, uploadUrl);
                    appFileService.add(appFile);

                    Map<String, String> map = new HashMap<>();
                    map.put("file_id", appFile.getId());//用于保存和回显
                    map.put("file_path", Constants.staticPrefix + Constants.imagePath + appFile.getFilePath());
                    filePath.add(map);
                    logger.info(JSON.toJSONString(filePath));
                }
            } catch(Exception e) {
                dto.ReturnFail(null, ErrorCode.FAILURE);
                return JSON.toJSONString(dto);
            }
        }
        logger.info(JSON.toJSONString(filePath));
        dto.ReturnSuccess(JSON.toJSONString(filePath), ErrorCode.SUCCESS);
        logger.info("[FileController] upload 文件上传成功");
        return JSON.toJSONString(dto);
    }

    /**
     * 返回上传路径
     * @return
     */
    private String retUploadPath() {
        //String basePath = request.getSession().getServletContext().getRealPath(Constants.tempImagePath);
        String basePath = appPath;
        if(basePath.endsWith("/") || basePath.endsWith("\\")
                || basePath.endsWith(File.separator))
        {
            basePath = basePath.substring(0,basePath.length() - 1) + Constants.imagePath;
        } else {
            basePath += Constants.imagePath;
        }
        return basePath;
    }

    @RequestMapping(value = "/delete")
    @ResponseBody
    public String delete(HttpServletRequest request) {
        Dto<String> dto = new Dto<>();
        User user = (User)request.getSession().getAttribute("userSession");
        if(null == user){
            logger.debug("[FileController] delete 用户未登录");
            dto.ReturnFail(null, ErrorCode.USER_NOT_LOGIN);
            return JSON.toJSONString(dto);
        }

        String fileId = request.getParameter("fileId");;
        AppFile appFile = appFileMapper.selectByPrimaryKey(fileId);
        if(null != appFile) {
            try {
                boolean result = false;
                //文件保存路径
                String filePath = appFile.getFilePath();
                if (StringUtils.isNotBlank(filePath) && filePath.contains(Constants.staticPrefix)) {
                    filePath = filePath.replace(Constants.staticPrefix, "");
                }
                //url路径
                String workPath = retUploadPath();
                //创建文件对象
                File file = new File(workPath + filePath);
                // 删除文件
                if (file != null && file.exists()) {
                    result = file.delete();
                }
                if(result) {
                    appFileMapper.deleteByPrimaryKey(fileId);
                }
            } catch (Exception e) {
                logger.debug("[FileController] delete 删除失败");
                dto.ReturnFail(null, ErrorCode.FAILURE);
                return JSON.toJSONString(dto);
            }
        } else {
            logger.debug("[FileController] delete 删除失败");
            dto.ReturnFail(null, ErrorCode.FAILURE);
            return JSON.toJSONString(dto);
        }

        dto.ReturnSuccess(null, ErrorCode.SUCCESS);
        return JSON.toJSONString(dto);
    }

    @RequestMapping(value = "/download/{fileId}")
    @ResponseBody
    public String download(HttpServletRequest request,
                           HttpServletResponse response, @PathVariable String fileId) {
        Dto<String> dto = new Dto<>();
        User user = (User)request.getSession().getAttribute("userSession");
        if(null == user){
            logger.debug("[FileController] download 用户未登录");
            dto.ReturnFail(null, ErrorCode.USER_NOT_LOGIN);
            return JSON.toJSONString(dto);
        }

        AppFile appFile = appFileMapper.selectByPrimaryKey(fileId);

        if(appFile != null) {
            try {
                String filePath = appFile.getFilePath();
                if (StringUtils.isNotBlank(filePath) && filePath.contains(Constants.staticPrefix)) {
                    filePath = filePath.replace(Constants.staticPrefix, "");
                }
                //url路径
                String workPath = retUploadPath();
                //创建文件对象
                File file = new File(workPath + filePath);
                // 删除文件
                if (file != null && file.exists()) {
                    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
                    byte[] buf = new byte[1024];
                    int len = 0;
                    response.reset(); // 非常重要
                    response.setContentType("application/x-msdownload");
                    response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
                    OutputStream os = response.getOutputStream();
                    while ((len = bis.read(buf)) > 0)
                        os.write(buf, 0, len);
                    bis.close();
                    os.close();
                    dto.ReturnSuccess(null, ErrorCode.SUCCESS);
                    return JSON.toJSONString(dto);
                }
            } catch (Exception e) {
                logger.info("[FileController] download 下载失败：{}", e.getMessage());
            }
        }

        dto.ReturnFail(null, ErrorCode.FAILURE);
        return JSON.toJSONString(dto);
    }
}
